package com.wuyou.sso.component;

import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import com.wuyou.sso.domain.vo.UserVO;
import com.wuyou.sso.common.enums.LoginTypeEnum;
import com.wuyou.sso.handler.login.LoginHandler;
import com.wuyou.sso.handler.login.UsernamePasswordHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.List;

/**
 * LoginFactory
 *
 * @Date 2025/4/24 17:14
 * @Author 无忧
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class LoginFactory {


    private final List<LoginHandler> loginHandlers;



    public UserVO handle(String loginStr){
        int index = loginStr.lastIndexOf(StrUtil.AT);
        LoginHandler loginHandler = getDefaultLoginHandler();
        String identify = StrUtil.EMPTY;
        if (index != -1) {
            identify = loginStr.substring(0, index);
            String type = loginStr.substring(index + 1);
            loginHandler = chooseHandler(type);
        }
        // 默认登录处理器下，强制将用户输入字符串作为登录用户名,避免邮箱中也有@符号等造成用户名被截断
        if (loginHandler instanceof UsernamePasswordHandler) {
            identify = loginStr;
        }
        //判空处理
        Assert.notNull(loginHandler, "loginHandler不可为空");
        return loginHandler.handle(identify);
    }

    /**
     * 根据登录参数获取登录处理器，登录参数不存在的话,获取默认的登录处理器类型(普通客户端登录用户加解密)
     *
     * @param type 登录类型的字符串表达
     * @return 一个必定可用的登录处理器
     */
    private LoginHandler chooseHandler(String type) {
        LoginTypeEnum loginTypeEnum = EnumUtil.likeValueOf(LoginTypeEnum.class, type);
        for (LoginHandler handler : loginHandlers) {
            if (loginTypeEnum == null) {
                return getDefaultLoginHandler();
            } else {
                if (handler.support(loginTypeEnum)) {
                    return handler;
                }
            }
        }
        // NOTE:理论上绝对不可能走到这里哒
        return null;
    }

    /**
     * 获取默认登录处理器
     *
     * @return
     */
    private LoginHandler getDefaultLoginHandler() {
        for (LoginHandler loginHandler : loginHandlers) {
            if (loginHandler.support(LoginTypeEnum.PWD)) {
                return loginHandler;
            }
        }
        // NOTE:理论上绝对不可能走到这里
        return null;
    }
}
